home *** CD-ROM | disk | FTP | other *** search
/ SGI Hot Mix 17 / Hot Mix 17.iso / HM17_SGI / research / examples / demo / demosrc / d_object3d.pro < prev    next >
Text File  |  1997-07-08  |  57KB  |  1,675 lines

  1. ; $Id: d_object3d.pro,v 1.29 1997/04/25 22:40:20 alan Exp $
  2. ;
  3. ;  Copyright (c) 1997, Research Systems, Inc. All rights reserved.
  4. ;       Unauthorized reproduction prohibited.
  5. ;
  6. ;+
  7. ;  FILE:
  8. ;       d_object3d.pro
  9. ;
  10. ;  CALLING SEQUENCE: d_object3d
  11. ;
  12. ;  PURPOSE:
  13. ;       Shows geometric objects (molecules and others.)
  14. ;
  15. ;  MAJOR TOPICS: Visualizaton and widgets
  16. ;
  17. ;  CATEGORY:
  18. ;       IDL 5.0
  19. ;
  20. ;  INTERNAL FUNCTIONS and PROCEDURES:
  21. ;       fun makespheres         - Create a shere
  22. ;       fun makemolecule        - Create a molecule
  23. ;       fun moleread            - Read the molecule file
  24. ;       pro new_select          - Handle a new selection
  25. ;       pro panimate            - Animate (with pattern keyword)
  26. ;       pro o3d_animate             - Animate (with pattern keyword)
  27. ;       pro toggle_state        - Toggle off and on
  28. ;       fun read_noff           - Read the object file
  29. ;       pro d_object3d_Event       - Event handler
  30. ;       pro d_object3d_Cleanup    - Cleanup
  31. ;       pro d_object3d            - Main procedure
  32. ;
  33. ;  EXTERNAL FUNCTIONS, PROCEDURES, and FILES:
  34. ;       pro gettips             - Get tip text structure.
  35. ;       pro widtips             - Create widget text for tips.
  36. ;       pro puttips             - Change the text display (tip)
  37. ;       object3d.txt
  38. ;       object3d.tip
  39. ;       knot.nof
  40. ;       seashell.nof
  41. ;       teapot.nof
  42. ;       aspartam.mol
  43. ;       caffeine.mol
  44. ;       valium.mol
  45. ;       pro orb__define.pro  - Create an orb object
  46. ;       pro trackball__define.pro  - Create a trackball object
  47. ;
  48. ;  REFERENCE: IDL Reference Guide, IDL User's Guide
  49. ;
  50. ;  NAMED STRUCTURES:
  51. ;       none.
  52. ;
  53. ;  COMMON BLOCS:
  54. ;       none.
  55. ;
  56. ;   MODIFICATION HISTORY:
  57. ;       9/96,   DD   - Written.
  58. ;       10/96,  DAT  - New GUI and combining molecule and objects.
  59. ;-
  60. ;----------------------------------------------------------------------
  61. ;
  62. ;  Purpose:  Create a sphere for each atom type.
  63. ;
  64. function makespheres
  65.  
  66.     o = objarr(8)
  67.  
  68.     o(0) = OBJ_NEW('orb', COLOR=[128,128,128], RADIUS=1.5)  ; C
  69.     o(1) = OBJ_NEW('orb', COLOR=[255,255,255], RADIUS=0.9)  ; H
  70.     o(2) = OBJ_NEW('orb', COLOR=[0,0,255],     RADIUS=1.5)  ; N
  71.     o(3) = OBJ_NEW('orb', COLOR=[230,230,0],   RADIUS=1.5)  ; S
  72.     o(4) = OBJ_NEW('orb', COLOR=[25,25,0],     RADIUS=1.5)  ; X
  73.     o(5) = OBJ_NEW('orb', COLOR=[240,0,153],   RADIUS=4.7)  ; Ce
  74.     o(6) = OBJ_NEW('orb', COLOR=[204,25,230],  RADIUS=1.3)  ; BR
  75.     o(7) = OBJ_NEW('orb', COLOR=[255,0,0],     RADIUS=1.46) ; O
  76.  
  77.     RETURN, o
  78. end
  79.  
  80.  
  81. ;----------------------------------------------------------------------
  82. ;
  83. ;  Purpose:  Create the molecule. Return it in a model.
  84. ;
  85. function makemolecule, $
  86.     n_atoms, $        ; IN: number of atoms in the molecule
  87.     atom_xyz, $       ; IN: position of each atoms
  88.     atoms, $          ; IN: atom type
  89.     objs              ; IN: atom object
  90.  
  91.     m = OBJ_NEW('IDLgrModel')
  92.  
  93.     for i=0,n_atoms-1 do begin
  94.         s = objs(atoms(i))
  95.         s->GetProperty, POBJ=sh
  96.         sh->GetProperty, COLOR=col, POLY=pmesh
  97.         p = OBJ_NEW('IDLgrPolygon', SHARE_DATA=sh, POLY=pmesh, COLOR=col)
  98.         p->SetProperty, SHADING=1, UVALUE=-1
  99.  
  100.         mm = OBJ_NEW('IDLgrModel', /SELECT_TARGET)
  101.         mm->SetProperty, UVALUE=atoms(i)
  102.         mm->Translate, atom_xyz(0,i), atom_xyz(1,i), atom_xyz(2,i)
  103.         mm->Add, p
  104.  
  105.         m->Add, mm
  106.     endfor
  107.  
  108.     RETURN, m
  109. end
  110.  
  111. ;----------------------------------------------------------------------
  112. ;
  113. ;  Purpose:  Read the molecule data input file.
  114. ;
  115. function molread, $
  116.     file, $          ; IN: filename
  117.     atom_xyz_r, $
  118.     atoms_r
  119.  
  120.     n_atoms = 0
  121.     atom_xyz = FLTARR(3,1000)
  122.     atoms = INTARR(1000)
  123.  
  124.     GET_LUN, lun
  125.  
  126.     OPENR, lun, filepath(file, $
  127.                 SUBDIR=['examples','demo','demodata'])
  128.  
  129.     s = " "
  130.  
  131.     while (n_atoms LT 1000) do begin
  132.  
  133.         on_ioerror, endoffile
  134.         READF, lun, s
  135.  
  136.         i = STRPOS(s,":")
  137.  
  138.         if (i NE -1) then begin
  139.             READS, strmid(s,i+1,strlen(s)-i+1),x,y,z
  140.             a_type = -1
  141.  
  142.             case strmid(s,0,2) of
  143.                 "C:" : a_type = 0
  144.                 "H:" : a_type = 1
  145.                 "N:" : a_type = 2
  146.                 "S:" : a_type = 3
  147.                 "X:" : a_type = 4
  148.                 "Ce" : a_type = 5
  149.                 "BR" : a_type = 6
  150.                 "O:" : a_type = 7
  151.                 else : a_type = -1
  152.             endcase
  153.  
  154.             if (a_type NE -1) then begin
  155.                 atom_xyz(0,n_atoms) = x
  156.                 atom_xyz(1,n_atoms) = y
  157.                 atom_xyz(2,n_atoms) = z
  158.                 atoms(n_atoms) = a_type
  159.                 n_atoms = n_atoms + 1
  160.             endif
  161.         endif
  162.     endwhile
  163.  
  164.     endoffile:
  165.  
  166.     CLOSE, lun
  167.  
  168.     FREE_LUN,lun
  169.  
  170.     if (n_atoms GE 0) then begin
  171.         atoms_r = atoms(0:n_atoms-1)
  172.         atom_xyz_r = atom_xyz(*,0:n_atoms-1)
  173.     end
  174.  
  175.     RETURN, n_atoms
  176.  
  177. end   ;   of  molread
  178.  
  179. ;----------------------------------------------------------------------
  180. ;
  181. ;  Purpose:  Reinitialize the selection state (picking).
  182. ;
  183. pro new_select, $
  184.     state, $
  185.     obj=target
  186.  
  187.     if (state.is_sel NE 0) then begin
  188.         state.cur_sel->SetProperty,STYLE=2
  189.         state.is_sel = 0
  190.     endif
  191.  
  192.     if (N_ELEMENTS(target) NE 0) then begin
  193.         state.is_sel = 1
  194.         state.cur_sel = target
  195.         state.cur_sel->SetProperty, STYLE=1
  196.     endif
  197. end      ;     of new_select
  198.  
  199. ;----------------------------------------------------------------------
  200. ;
  201. ;  Purpose:  Animate
  202. ;
  203. pro panimate, $
  204.     state, $  ;  IN: state structure
  205.     what      ;  IN:  what to animate
  206.  
  207.     state.oSurface(state.cur_obj)->GetProperty, FILL_PATTERN=pobj
  208.  
  209.     spacing=5.0
  210.     for i=0,180,10 do begin
  211.        pobj->SetProperty, ORIENTATION=i, SPACING=spacing
  212.        state.oWindow->Draw, state.oView
  213.        spacing = spacing + 1.0
  214.        if (spacing GE 20.0) then spacing = 5.0
  215.     endfor
  216. end
  217.  
  218. ;----------------------------------------------------------------------
  219. ;
  220. ;  Purpose:  Animate
  221. ;
  222. pro o3d_animate, $
  223.     state, $  ;  IN: state structure
  224.     what      ;  IN:  what to animate
  225.  
  226.     ; get the verts
  227.     ;
  228.     state.oSurface(state.cur_obj)->GetProperty, DATA=verts
  229.     v1 = verts
  230.  
  231.     for i=10,2,-2 do begin
  232.         v1(2,*) = verts(2,*)*(float(i)/10.0)
  233.         state.oSurface(state.cur_obj)->SetProperty,DATA=v1
  234.         state.oWindow->Draw, state.oView
  235.     endfor
  236.     for i=-2,-10,-2 do begin
  237.         v1(2,*) = verts(2,*)*(float(i)/10.0)
  238.         state.oSurface(state.cur_obj)->SetProperty,DATA=v1
  239.         state.oWindow->Draw, state.oView
  240.     endfor
  241.     for i=-10,-2,2 do begin
  242.         v1(2,*) = verts(2,*)*(float(i)/10.0)
  243.         state.oSurface(state.cur_obj)->SetProperty,DATA=v1
  244.         state.oWindow->Draw, state.oView
  245.     endfor
  246.     for i=2,10,2 do begin
  247.         v1(2,*) = verts(2,*)*(float(i)/10.0)
  248.         state.oSurface(state.cur_obj)->SetProperty,DATA=v1
  249.         state.oWindow->Draw, state.oView
  250.     endfor
  251.  
  252.     ; prevent decay...
  253.     ;
  254.     state.oSurface(state.cur_obj)->SetProperty,DATA=verts
  255.  
  256. end  ;   of  o3d_animate
  257.  
  258. ;----------------------------------------------------------------------
  259. ;
  260. ;  Purpose:   toggle off and on state.
  261. ;
  262. function Toggle_state, $
  263.     wid     ;  IN: widget identifier
  264.  
  265.     WIDGET_CONTROL, wid, GET_VALUE=name
  266.  
  267.     s = STRPOS(name,'(off)')
  268.     if (s NE -1) then begin
  269.         STRPUT,name,'(on )',s
  270.         ret = 1
  271.     endif else begin
  272.         s = STRPOS(name,'(on )')
  273.         STRPUT,name,'(off)',s
  274.         ret = 0
  275.     endelse
  276.  
  277.     WIDGET_CONTROL, wid, SET_VALUE=name
  278.  
  279.     RETURN, ret
  280. end    ;   of  Toggle_state,
  281.  
  282. ;----------------------------------------------------------------------
  283. ;
  284. ;  Purpose: This reads a modified .off format
  285. ;           file (header removed, one ptype...)
  286. ;           
  287. function read_noff, $
  288.     file, $       ; IN: filename
  289.     parent, $     ; IN: parent model for the created polyline object
  290.     xr, $         ; OUT: x radius
  291.     yr, $         ; OUT: y radius
  292.     zr            ; OUT: z radius
  293.  
  294.     s = ' '
  295.     npsize = 1
  296.  
  297.     GET_LUN, lun
  298.  
  299.     OPENR, lun, filepath(file, $
  300.                 SUBDIR=['examples','demo','demodata'])
  301.  
  302.     nverts=0L
  303.     npatches=0L
  304.     nconn=0L
  305.     psize=0L
  306.     READF, lun, nverts, npatches, nconn, psize
  307.  
  308.     x = FLTARR(nverts, /NOZERO)
  309.     y = FLTARR(nverts, /NOZERO)
  310.     z = FLTARR(nverts, /NOZERO)
  311.  
  312.     for i=0, nverts-1 do begin
  313.         READF,lun,xp,yp,zp
  314.         x(i)=xp
  315.         y(i)=yp
  316.         z(i)=zp
  317.     endfor
  318.  
  319.     if (psize NE -1) then begin
  320.         msize=npatches*(psize+1)
  321.     endif else begin
  322.         msize = nconn + npatches
  323.     endelse
  324.  
  325.     mesh = LONARR(msize)
  326.  
  327.     j = 0
  328.     m1=0L
  329.     m2=0L
  330.     m3=0L
  331.     m4=0L
  332.     for i=0,npatches-1 do begin
  333.         if (psize NE -1) then begin
  334.             mesh(j) = psize
  335.             if (psize EQ 3) then begin
  336.                 READF, lun, dummy, m1, m2, m3
  337.                 mesh(j+1)=m1
  338.                 mesh(j+2)=m2
  339.                 mesh(j+3)=m3
  340.             endif else begin
  341.                 READF, lun, dummy, m1, m2, m3, m4
  342.                 mesh(j+1)=m1
  343.                 mesh(j+2)=m2
  344.                 mesh(j+3)=m3
  345.                 mesh(j+4)=m4
  346.             endelse
  347.                 j = j + psize+1
  348.         endif else begin
  349.             READF, lun, s
  350.             READS, s, npsize
  351.             arr = LONARR(npsize+1)
  352.             READS, s, arr
  353.             mesh(j:j+npsize) = arr
  354.             j = j + npsize+1
  355.         endelse
  356.     endfor
  357.     ;CLOSE, lun
  358.  
  359.     FREE_LUN, lun
  360.  
  361.     ;xr = FLTARR(2)
  362.     ;xr(0) = MIN(x)
  363.     ;xr(1) = MAX(x)
  364.     xmin=MIN(x, max=xmax)
  365.     xr=[xmin, xmax]
  366.  
  367.     ;yr = FLTARR(2)
  368.     ;yr(0) = MIN(y)
  369.     ;yr(1) = MAX(y)
  370.     ymin=MIN(y, max=ymax)
  371.     yr=[ymin, ymax]
  372.  
  373.     ;zr = FLTARR(2)
  374.     ;zr(0) = MIN(z)
  375.     ;zr(1) = MAX(z)
  376.     zmin=MIN(z, max=zmax)
  377.     zr=[zmin, zmax]
  378.  
  379.     ; remap to +-1
  380.     ;
  381.     ;sc = FLTARR(3)
  382.     ;sc(0) = xr(1) - xr(0)
  383.     ;sc(1) = yr(1) - yr(0)
  384.     ;sc(2) = zr(1) - zr(0)
  385.     sc = MAX([xmax - xmin, ymax - ymin, zmax - zmin])
  386.  
  387.     ;xr(0) = (xr(1) + xr(0))/2.0
  388.     ;yr(0) = (yr(1) + yr(0))/2.0
  389.     ;zr(0) = (zr(1) + zr(0))/2.0
  390.     xav = (xmax + xmin)/2.0
  391.     yav = (ymax + ymin)/2.0
  392.     zav = (zmax + zmin)/2.0
  393.  
  394.     ;if ((sc(2) GT sc(1)) AND (sc(2) GT sc(0))) then begin
  395.     ;    sc(0) = sc(2)
  396.     ;endif else if ((sc(1) GT sc(0)) AND (sc(1) GT sc(2))) then begin
  397.     ;    sc(0) = sc(1)
  398.     ;endif
  399.     ;;;sc[0] = MAX(sc)
  400.     
  401.  
  402.     ;for i=0,nverts-1 do begin
  403.     ;    x(i) = (x(i)-xr(0))/sc(0)
  404.     ;    y(i) = (y(i)-yr(0))/sc(0)
  405.     ;    z(i) = (z(i)-zr(0))/sc(0)
  406.     ;endfor
  407.     ;;x = (x-xr(0))/sc(0)
  408.     ;;y = (y-yr(0))/sc(0)
  409.     ;;z = (z-zr(0))/sc(0)
  410.     x = (x-xav)/sc
  411.     y = (y-yav)/sc
  412.     z = (z-zav)/sc
  413.  
  414.     xr = [-0.7, 0.7]
  415.     yr = [-0.7, 0.7]
  416.     zr = [-0.7, 0.7]
  417.  
  418.     s = OBJ_NEW("IDLgrPolygon", TRANSPOSE([[x],[y],[z]]), $
  419.             SHADING=1, $
  420.             POLY=mesh, COLOR=[200,200,200])
  421.  
  422.     parent->Add, s
  423.  
  424.     RETURN,s
  425.  
  426. end    ;   of read_noff
  427.  
  428. ;----------------------------------------------------------------------
  429. ;
  430. ;  Purpose: This reads a flat binary file containing the mesh
  431.  
  432. ;           
  433. function object3d_read_data, $
  434.     file, $       ; IN: filename
  435.     parent, $     ; IN: parent model for the created polyline object
  436.     xr, $         ; OUT: x radius
  437.     yr, $         ; OUT: y radius
  438.     zr            ; OUT: z radius
  439.  
  440.     s = ' '
  441.  
  442.     RESTORE, filepath(file, $
  443.                 SUBDIR=['examples','demo','demodata'])
  444.  
  445.     xmin=MIN(x, max=xmax)
  446.     xr=[xmin, xmax]
  447.  
  448.     ymin=MIN(y, max=ymax)
  449.     yr=[ymin, ymax]
  450.  
  451.     zmin=MIN(z, max=zmax)
  452.     zr=[zmin, zmax]
  453.  
  454.     sc = MAX([xmax - xmin, ymax - ymin, zmax - zmin])
  455.  
  456.     xav = (xmax + xmin)/2.0
  457.     yav = (ymax + ymin)/2.0
  458.     zav = (zmax + zmin)/2.0
  459.  
  460.     x = (x-xav)/sc
  461.     y = (y-yav)/sc
  462.     z = (z-zav)/sc
  463.  
  464.     xr = [-0.7, 0.7]
  465.     yr = [-0.7, 0.7]
  466.     zr = [-0.7, 0.7]
  467.  
  468.     s = OBJ_NEW("IDLgrPolygon", TRANSPOSE([[x],[y],[z]]), $
  469.             SHADING=1, $
  470.             POLY=mesh, COLOR=[200,200,200])
  471.  
  472.     parent->Add, s
  473.  
  474.     RETURN,s
  475.  
  476. end    ;   of object3d_read_data
  477.  
  478. ;----------------------------------------------------------------------
  479. ;
  480. ;  Purpose: Event handler of the geometric shapes.
  481. ;
  482. pro d_object3d_event, $
  483.     sEvent          ; IN: event structure
  484.  
  485.     ;  Quit the application using the close box.
  486.     ;
  487.     if (TAG_NAMES(sEvent, /STRUCTURE_NAME) EQ $
  488.         'WIDGET_KILL_REQUEST') then begin
  489.         WIDGET_CONTROL, sEvent.top, /DESTROY
  490.         RETURN
  491.     endif
  492.  
  493.     WIDGET_CONTROL, sEvent.id, GET_UVALUE=uval
  494.  
  495.     case uval of
  496.  
  497.         ;  Set scaling.
  498.         ;
  499.         'SCALING': begin
  500.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  501.             WIDGET_CONTROL, $
  502.                 state.widgetIDStr.wScalingSlider, GET_VALUE=scale
  503.             scale = 0.75 + FLOAT(scale) / 100.0
  504.             scalep = scale*100.0
  505.             scalingString = 'Scaling : ' + STRING(scalep, $
  506.                 FORMAT='(f5.1)') + ' %'
  507.             WIDGET_CONTROL, state.widgetIDStr.wScalingLabel, $
  508.                 SET_VALUE=scalingString
  509.                 
  510.             transform = [[scale*0.7, 0, 0, 0.0], [0, scale*0.7, 0, 0.0], $
  511.                 [0, 0, scale*0.7, 0.0], [0, 0, 0, 1]]
  512.             transformmol = [[scale*.3, 0, 0, 0.0], [0, scale*.3, 0, 0.0], $
  513.                 [0, 0, scale*.3, 0.0], [0, 0, 0, 1]]
  514.             state.oMoleModel->SetProperty, TRANSFORM = transformmol
  515.             state.oShapeModel->SetProperty, TRANSFORM = transform
  516.           
  517.             WIDGET_CONTROL, state.widgetIDStr.wBase, /HOURGLASS
  518.             state.oWindow->draw,State.oView
  519.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  520.         end        ;  of SCALING
  521.  
  522.         ;  Set line thickness to 1 point.
  523.         ;
  524.         'THCK1': begin
  525.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  526.             WIDGET_CONTROL, state.widgetIDStr.wThk1, SENSITIVE=0
  527.             WIDGET_CONTROL, state.widgetIDStr.wThk3, SENSITIVE=1
  528.             WIDGET_CONTROL, state.widgetIDStr.wThk5, SENSITIVE=1
  529.             WIDGET_CONTROL, state.widgetIDStr.wThk7, SENSITIVE=1
  530.             for i=0,state.max_obj-1 do begin
  531.                 state.oSurface(i)->SetProperty,thick=1.0
  532.             endfor
  533.             state.oWindow->Draw, state.oView
  534.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  535.         end        ;  of THCK1
  536.  
  537.         ;  Set line thickness to 3 points.
  538.         ;
  539.         'THCK3': begin
  540.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  541.             WIDGET_CONTROL, state.widgetIDStr.wThk1, SENSITIVE=1
  542.             WIDGET_CONTROL, state.widgetIDStr.wThk3, SENSITIVE=0
  543.             WIDGET_CONTROL, state.widgetIDStr.wThk5, SENSITIVE=1
  544.             WIDGET_CONTROL, state.widgetIDStr.wThk7, SENSITIVE=1
  545.             for i=0,state.max_obj-1 do begin
  546.                 state.oSurface(i)->SetProperty,thick=3.0
  547.             endfor
  548.             state.oWindow->Draw, state.oView
  549.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  550.         end        ;  of THCK3
  551.  
  552.         ;  Set line thickness to 5 points.
  553.         ;
  554.         'THCK5': begin
  555.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  556.             WIDGET_CONTROL, state.widgetIDStr.wThk1, SENSITIVE=1
  557.             WIDGET_CONTROL, state.widgetIDStr.wThk3, SENSITIVE=1
  558.             WIDGET_CONTROL, state.widgetIDStr.wThk5, SENSITIVE=0
  559.             WIDGET_CONTROL, state.widgetIDStr.wThk7, SENSITIVE=1
  560.             for i=0,state.max_obj-1 do begin
  561.                 state.oSurface(i)->SetProperty,thick=5.0
  562.             endfor
  563.             state.oWindow->Draw, state.oView
  564.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  565.         end        ;  of THCK5
  566.  
  567.         ;  Set line thickness to 7 points.
  568.         ;
  569.         'THCK7': begin
  570.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  571.             WIDGET_CONTROL, state.widgetIDStr.wThk1, SENSITIVE=1
  572.             WIDGET_CONTROL, state.widgetIDStr.wThk3, SENSITIVE=1
  573.             WIDGET_CONTROL, state.widgetIDStr.wThk5, SENSITIVE=1
  574.             WIDGET_CONTROL, state.widgetIDStr.wThk7, SENSITIVE=0
  575.             for i=0,state.max_obj-1 do begin
  576.                 state.oSurface(i)->SetProperty,thick=7.0
  577.             endfor
  578.             state.oWindow->Draw, state.oView
  579.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  580.         end        ;  of THCK7
  581.  
  582.         ;  Animate the object.
  583.         ;
  584.         'PANIMATE': begin
  585.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  586.             WIDGET_CONTROL, state.widgetIDStr.wBase, SENSITIVE=0
  587.             panimate, state, 0
  588.             WIDGET_CONTROL, state.widgetIDStr.wBase, SENSITIVE=1
  589.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  590.         end        ;  of PANIMATE
  591.  
  592.         ;  Select and show a new geometric object.
  593.         ;
  594.         'OBJ': begin
  595.             WIDGET_CONTROL, /HOURGLASS
  596.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  597.             WIDGET_CONTROL, state.widgetIDStr.wBase, SENSITIVE=0
  598.             WIDGET_CONTROL, sEvent.id, GET_VALUE=bgroupIndex
  599.             if bgroupIndex LT state.max_obj then begin
  600.                 ;  Handle the shell, knot, teapot
  601.                 ;
  602.                 WIDGET_CONTROL, state.widgetIDStr.wEditButton, SENSITIVE=1
  603.                 state.oMoleModel->SetProperty, HIDE=1
  604.                 state.oView->SetProperty, COLOR=[0, 0, 0]
  605.                 state.oShapeModel->SetProperty, HIDE=0
  606.                 for i=0,state.max_obj-1 do begin
  607.                     state.oSurface(i)->SetProperty, HIDE=1
  608.                     state.sh(i)->SetProperty, HIDE=1 
  609.                 endfor
  610.                 state.cur_obj = bgroupIndex
  611.                 state.oSurface(state.cur_obj)->SetProperty, HIDE=0  
  612.                 if (state.edging EQ 1) then begin
  613.                     state.sh(state.cur_obj)->SetProperty, HIDE=0 
  614.                 endif
  615.  
  616.                 state.oWindow->Draw, state.oView
  617.                 textChange = ['inter','mouse']
  618.                 putTips, state.sText, state.wText[1], $
  619.                     textChange, [1,2]
  620.                 state.modelFlag = 1
  621.                 WIDGET_CONTROL, state.widgetIDStr.wBase, SENSITIVE=1
  622.                 WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  623.             endif else begin
  624.                 ;  Handle the molecules
  625.                 ;
  626.                 WIDGET_CONTROL, state.widgetIDStr.wEditButton, SENSITIVE=0
  627.                 new_select, state
  628.                 state.oMoleModel->SetProperty, HIDE=0
  629.                 state.oView->SetProperty, COLOR=[30, 90, 30]
  630.                 state.oShapeModel->SetProperty, HIDE=1
  631.                 for i=0,state.nMolecule*2-1 do begin
  632.                     state.oMolecule(i)->SetProperty, HIDE=1
  633.                 endfor
  634.  
  635.                 ;  bgroupIndex is the item number from the bgroup
  636.                 ;  the molecules are after the other objects in the bgroup
  637.                 ;
  638.                 state.cur_mol = bgroupIndex - state.max_obj
  639.                 state.oMolecule(state.cur_mol)->SetProperty, HIDE=0  
  640.                 state.oWindow->Draw, state.oView
  641.                 textChange = ['molec','right']
  642.                 putTips, state.sText, state.wText[1], $
  643.                     textChange, [1,2]
  644.     
  645.                 state.modelFlag = 0
  646.                 WIDGET_CONTROL, state.widgetIDStr.wBase, SENSITIVE=1
  647.                 WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  648.             endelse
  649.         end    ;   of OBJ
  650.  
  651.         ;  Add or remove the vertices colors.
  652.         ;
  653.         'VERTC' : begin
  654.  
  655.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  656.             j = Toggle_State(sEvent.id)
  657.             case j of
  658.  
  659.                 ;  Remove the colors.
  660.                 ;
  661.                 0: begin
  662.                     for i=0,state.max_obj-1 do begin
  663.                        state.oSurface(i)->SetProperty, VERT_COLORS=0
  664.                     endfor
  665.                 end      ;   of 0
  666.  
  667.                 ;  Add the colors.
  668.                 ;
  669.                 1: begin
  670.                     for i=0,state.max_obj-1 do begin
  671.                         state.oSurface(i)->SetProperty, $
  672.                             VERT_COLORS=state.vc
  673.                     endfor
  674.                 end      ;   of 0
  675.  
  676.             endcase
  677.             state.oWindow->Draw, state.oView
  678.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  679.         end    ;   of VERTC
  680.  
  681.         ;  Show the vertices as points.
  682.         ;
  683.         'POINTS' : BEGIN
  684.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  685.             for i=0,state.max_obj-1 do state.oSurface(i)->SetProperty,STYLE=0  
  686.             for i=0,state.max_obj-1 do begin
  687.                 state.oSurface(i)->SetProperty,hidden_line=0
  688.             endfor
  689.             state.oWindow->Draw, state.oView
  690.             WIDGET_CONTROL, state.widgetIDStr.wPointsButton, SENSITIVE=0
  691.             WIDGET_CONTROL, state.widgetIDStr.wWireButton, SENSITIVE=1
  692.             WIDGET_CONTROL, state.widgetIDStr.wSolidButton, SENSITIVE=1
  693.             WIDGET_CONTROL, state.widgetIDStr.wPointHButton, SENSITIVE=1
  694.             WIDGET_CONTROL, state.widgetIDStr.wWirehButton, SENSITIVE=1
  695.             WIDGET_CONTROL, state.widgetIDStr.wThickButton, SENSITIVE=1
  696.             WIDGET_CONTROL, state.widgetIDStr.wBottomButton, SENSITIVE=0
  697.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  698.         end   ;  of POINTS
  699.  
  700.         ;  Set the object style to wire.
  701.         ;
  702.         'WIRE' : BEGIN
  703.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  704.             for i=0,state.max_obj-1 do begin
  705.                 state.oSurface(i)->SetProperty,STYLE=1
  706.             endfor
  707.             for i=0,state.max_obj-1 do begin
  708.                 state.oSurface(i)->SetProperty,hidden_line=0
  709.             endfor
  710.             state.oWindow->Draw, state.oView
  711.             WIDGET_CONTROL, state.widgetIDStr.wPointsButton, SENSITIVE=1
  712.             WIDGET_CONTROL, state.widgetIDStr.wWireButton, SENSITIVE=0
  713.             WIDGET_CONTROL, state.widgetIDStr.wSolidButton, SENSITIVE=1
  714.             WIDGET_CONTROL, state.widgetIDStr.wPointHButton, SENSITIVE=1
  715.             WIDGET_CONTROL, state.widgetIDStr.wWirehButton, SENSITIVE=1
  716.             WIDGET_CONTROL, state.widgetIDStr.wThickButton, SENSITIVE=1
  717.             WIDGET_CONTROL, state.widgetIDStr.wBottomButton, SENSITIVE=0
  718.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  719.         end   ;  of WIRE
  720.  
  721.         ;  Set the object style to solid surface.
  722.         ;
  723.         'SOLID' : BEGIN
  724.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  725.             for i=0,state.max_obj-1 do begin
  726.                 state.oSurface(i)->SetProperty,STYLE=2
  727.             endfor
  728.             for i=0,state.max_obj-1 do begin
  729.                 state.oSurface(i)->SetProperty,hidden_line=0
  730.             endfor
  731.             state.oWindow->Draw, state.oView
  732.             WIDGET_CONTROL, state.widgetIDStr.wPointsButton, SENSITIVE=1
  733.             WIDGET_CONTROL, state.widgetIDStr.wWireButton, SENSITIVE=1
  734.             WIDGET_CONTROL, state.widgetIDStr.wSolidButton, SENSITIVE=0
  735.             WIDGET_CONTROL, state.widgetIDStr.wPointHButton, SENSITIVE=1
  736.             WIDGET_CONTROL, state.widgetIDStr.wWirehButton, SENSITIVE=1
  737.             WIDGET_CONTROL, state.widgetIDStr.wThickButton, SENSITIVE=0
  738.             WIDGET_CONTROL, state.widgetIDStr.wBottomButton, SENSITIVE=1
  739.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  740.         end   ;  of SOLID
  741.  
  742.         ;  Set the object style to hidden points.
  743.         ;
  744.         'POINTSH' : BEGIN
  745.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  746.             for i=0,state.max_obj-1 do begin
  747.                 state.oSurface(i)->SetProperty, STYLE=0 
  748.             endfor
  749.             for i=0,state.max_obj-1 do begin
  750.                 state.oSurface(i)->SetProperty, /HIDDEN_LINE
  751.             endfor
  752.             state.oWindow->Draw, state.oView
  753.             WIDGET_CONTROL, state.widgetIDStr.wPointsButton, SENSITIVE=1
  754.             WIDGET_CONTROL, state.widgetIDStr.wWireButton, SENSITIVE=1
  755.             WIDGET_CONTROL, state.widgetIDStr.wSolidButton, SENSITIVE=1
  756.             WIDGET_CONTROL, state.widgetIDStr.wPointHButton, SENSITIVE=0
  757.             WIDGET_CONTROL, state.widgetIDStr.wWirehButton, SENSITIVE=1
  758.             WIDGET_CONTROL, state.widgetIDStr.wThickButton, SENSITIVE=1
  759.             WIDGET_CONTROL, state.widgetIDStr.wBottomButton, SENSITIVE=0
  760.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  761.         end   ;  of  POINTSH
  762.  
  763.         ;  Set the object style to hidden wire.
  764.         ;
  765.         'WIREH' : BEGIN
  766.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  767.             for i=0,state.max_obj-1 do begin
  768.                 state.oSurface(i)->SetProperty,STYLE=1   
  769.             endfor
  770.             for i=0,state.max_obj-1 do begin
  771.                 state.oSurface(i)->SetProperty,/hidden_line
  772.             endfor
  773.             state.oWindow->Draw, state.oView
  774.             WIDGET_CONTROL, state.widgetIDStr.wPointsButton, SENSITIVE=1
  775.             WIDGET_CONTROL, state.widgetIDStr.wWireButton, SENSITIVE=1
  776.             WIDGET_CONTROL, state.widgetIDStr.wSolidButton, SENSITIVE=1
  777.             WIDGET_CONTROL, state.widgetIDStr.wPointHButton, SENSITIVE=1
  778.             WIDGET_CONTROL, state.widgetIDStr.wWirehButton, SENSITIVE=0
  779.             WIDGET_CONTROL, state.widgetIDStr.wThickButton, SENSITIVE=1
  780.             WIDGET_CONTROL, state.widgetIDStr.wBottomButton, SENSITIVE=0
  781.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  782.         end   ;  of  WIREH
  783.  
  784.         ;  Add or remove the color of the polygon bottom side.
  785.         ;
  786.         'BOTTOM' : begin
  787.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  788.             j = Toggle_State(sEvent.id)
  789.  
  790.             if (j EQ 0) then begin
  791.                 for i=0,state.max_obj-1 do begin
  792.                     state.oSurface(i)->SetProperty, BOTTOM=[64,192,128]
  793.                 endfor
  794.             endif else begin
  795.                 for i=0,state.max_obj-1 do begin
  796.                     state.oSurface(i)->SetProperty, BOTTOM=0
  797.                 endfor
  798.             endelse
  799.  
  800.             state.oWindow->Draw, state.oView
  801.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  802.         end   ;  of  BOTTOM
  803.  
  804.         ;  Add or remove the back face culiing option. Back face culling
  805.         ;  on will hide the polygon when seen from its bottom side.
  806.         ;
  807.         'BACKF' : begin
  808.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  809.             j = Toggle_State(sEvent.id)
  810.             for i=0, state.max_obj-1 do begin
  811.                 state.oSurface(i)->SetProperty, REJECT=j
  812.             endfor
  813.             state.oWindow->Draw, state.oView
  814.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  815.         end   ;  of  BACKF
  816.  
  817.         ;  Add or remove edges.
  818.         ;
  819.         'EDGING' : begin
  820.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  821.             state.edging = Toggle_State(sEvent.id)
  822.  
  823.             if (state.edging EQ 1) then begin
  824.             state.sh(state.cur_obj)->SetProperty, HIDE=0 
  825.             endif else begin
  826.             state.sh(state.cur_obj)->SetProperty, HIDE=1
  827.             endelse
  828.  
  829.             state.oWindow->Draw, state.oView
  830.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  831.         end   ;  of  EDGING
  832.  
  833.         ;  Set the drag quality to low.
  834.         ;
  835.         'LOW' : begin
  836.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  837.             state.dragq = 0  
  838.             WIDGET_CONTROL, state.widgetIDStr.wLowButton, SENSITIVE=0
  839.             WIDGET_CONTROL, state.widgetIDStr.wMediumButton, SENSITIVE=1
  840.             WIDGET_CONTROL, state.widgetIDStr.wHighButton, SENSITIVE=1
  841.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  842.         end   ;  of  LOW
  843.  
  844.         ;  Set the drag quality to medium.
  845.         ;
  846.         'MEDIUM' : begin
  847.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  848.             state.dragq = 1
  849.             WIDGET_CONTROL, state.widgetIDStr.wLowButton, SENSITIVE=1
  850.             WIDGET_CONTROL, state.widgetIDStr.wMediumButton, SENSITIVE=0
  851.             WIDGET_CONTROL, state.widgetIDStr.wHighButton, SENSITIVE=1
  852.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  853.         end   ;  of  MEDIUM
  854.  
  855.         ;  Set the drag quality to high.
  856.         ;
  857.         'HIGH' : begin
  858.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  859.             state.dragq = 2
  860.             WIDGET_CONTROL, state.widgetIDStr.wLowButton, SENSITIVE=1
  861.             WIDGET_CONTROL, state.widgetIDStr.wMediumButton, SENSITIVE=1
  862.             WIDGET_CONTROL, state.widgetIDStr.wHighButton, SENSITIVE=0
  863.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  864.         end   ;  of  HIGH
  865.  
  866.         ;  Set the object shading to flat.
  867.         ;
  868.         'FLAT' : BEGIN
  869.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  870.             for i=0,state.max_obj-1 do begin
  871.                 state.oSurface(i)->SetProperty, SHADING=0  
  872.             endfor
  873.             state.oWindow->Draw, state.oView
  874.             WIDGET_CONTROL, state.widgetIDStr.wFlatButton, $
  875.                 SENSITIVE=0
  876.             WIDGET_CONTROL, state.widgetIDStr.wGouraudButton, $
  877.                 SENSITIVE=1
  878.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  879.         end   ;  of  FLAT
  880.  
  881.         ;  Set the object shading to Gouraud.
  882.         ;
  883.         'GOURAUD' : BEGIN
  884.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  885.             for i=0,state.max_obj-1 do begin
  886.                 state.oSurface(i)->SetProperty, SHADING=1  
  887.             endfor
  888.             state.oWindow->Draw, state.oView
  889.             WIDGET_CONTROL, state.widgetIDStr.wFlatButton, $
  890.                 SENSITIVE=1
  891.             WIDGET_CONTROL, state.widgetIDStr.wGouraudButton, $
  892.                 SENSITIVE=0
  893.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  894.         end   ;  of GOURAUD
  895.  
  896.         ;  Reorient the object to its initial state.
  897.         ;
  898.         'RESETTRANSFORM' : begin
  899.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  900.             WIDGET_CONTROL, state.widgetIDStr.wBase, SENSITIVE=0
  901.             state.oShape0Model->SetProperty, TRANSFORM=state.tmg0
  902.             state.oShape1Model->SetProperty, TRANSFORM=state.tmg1
  903.             state.oSub1MoleModel->SetProperty, TRANSFORM=state.tmmolecule
  904.             state.oWindow->Draw, state.oView
  905.             WIDGET_CONTROL, state.widgetIDStr.wBase, SENSITIVE=1
  906.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  907.         end   ;  of RESETTRANSFORM
  908.  
  909.         ;  Handle the event of the drawing area.
  910.         ;
  911.         'DRAW': begin
  912.  
  913.             WIDGET_CONTROL, sEvent.top, GET_UVALUE=state, /NO_COPY
  914.  
  915.             ;  Handle the event for object selection.
  916.             ;
  917.             if (state.modelFlag eq 1) then begin
  918.  
  919.                 ;  Expose.
  920.                 ;
  921.                 if (sEvent.type EQ 4) then begin
  922.                     state.oWindow->draw, state.oView
  923.                 endif
  924.  
  925.                 ;  Handle trackball update
  926.                 ;
  927.                 bHaveTransform = state.oTrack->Update(sEvent, TRANSFORM=qmat )
  928.                 if (bHaveTransform NE 0) then begin
  929.                     state.oShape0Model->GetProperty, TRANSFORM=t
  930.                     mt = t # qmat
  931.                     state.oShape0Model->SetProperty,TRANSFORM=mt
  932.                     state.oShape1Model->SetProperty,TRANSFORM=mt
  933.                 endif
  934.  
  935.                 ;  Button press.
  936.                 ;
  937.                 if (sEvent.type EQ 0) then begin
  938.                     state.btndown = 1B
  939.                     state.oWindow->SetProperty, QUALITY=state.dragq
  940.                     WIDGET_CONTROL, state.wDraw, /DRAW_MOTION
  941.                 endif
  942.  
  943.                 ;  Button motion.
  944.                 ;
  945.                 if ((sEvent.type eq 2) and (state.btndown eq 1b)) then begin
  946.                     if (bHaveTransform) then begin
  947.                         state.oWindow->Draw, state.oView
  948.                     endif
  949.                 endif
  950.  
  951.                 ;  Button release.
  952.                 ;
  953.                 if (sEvent.type eq 1) then begin
  954.                     state.btndown = 0b
  955.                     state.oWindow->SetProperty, QUALITY=2
  956.                     state.oWindow->Draw, state.oView
  957.                     WIDGET_CONTROL, state.wDraw, DRAW_MOTION=0
  958.                 endif
  959.  
  960.             ; Handle the event for molecule selection
  961.             ;
  962.             endif else begin
  963.  
  964.                 ;  Expose.
  965.                 ;
  966.                 if (sEvent.type eq 4) then begin
  967.                     state.oWindow->Setproperty, QUALITY=2
  968.                     state.initial = 1
  969.                     state.oWindow->draw, state.oView
  970.                 endif
  971.  
  972.                 ;  Handle trackball update
  973.                 ;
  974.                 bHaveTransform = state.oTrack->Update(sEvent, TRANSFORM=qmat )
  975.                 if (bHaveTransform NE 0) then begin
  976.                     state.oSub1MoleModel->GetProperty, TRANSFORM=t
  977.                     mt = t # qmat
  978.                     state.oSub1MoleModel->SetProperty,TRANSFORM=mt
  979.                     state.oSub2MoleModel->SetProperty,TRANSFORM=mt
  980.                 endif
  981.  
  982.                 ;  Button press.
  983.                 ;
  984.                 if (sEvent.type EQ 0) then begin
  985.  
  986.                     ;  Handle the picking of an atom with
  987.                     ;  the right or center mouse button
  988.                     ;
  989.                     if ((sEvent.press EQ 4) OR (sEvent.press EQ 2)) then begin
  990.                         WIDGET_CONTROL, state.widgetIDStr.wBase, SENSITIVE=0
  991.                         picked = state.oWindow->select(state.oView, $
  992.                             [sEvent.x,sEvent.y]);
  993.                         si = size(picked)
  994.                         if (si(0) NE 0) then begin
  995.                             picked(0)->GetProperty, UVALUE=uval, TRANSFORM=tm
  996.                             case uval of
  997.                                 0: atm="C"
  998.                                 1: atm="H"
  999.                                 2: atm="N"
  1000.                                 3: atm="S"
  1001.                                 4: atm="X"
  1002.                                 5: atm="Ce"
  1003.                                 6: atm="Br"
  1004.                                 7: atm="O "
  1005.                                 else: atm="??"
  1006.                             endcase
  1007.                             str = string(tm(3,0), tm(3,1), tm(3,2), atm, $
  1008.                                 format='("X=", F6.2, ",Y=", F6.2,'+ $
  1009.                                 '",Z=", F6.2, ",Atom=", A2)')
  1010.                             new_select, state, OBJ=picked(0)->get()
  1011.                         endif else begin
  1012.                             str="No atom picked"
  1013.                             new_select, state
  1014.                         endelse
  1015.                         state.stext.text[9] = str
  1016.                         textChange = ['atomi', 'void']
  1017.                         putTips, state.sText, state.wText[1], $
  1018.                             textChange, [1,2]
  1019.                         state.oWindow->Draw, state.oView
  1020.                         WIDGET_CONTROL, state.widgetIDStr.wBase, SENSITIVE=1
  1021.  
  1022.                     ;  Handle the interactive change of orientation
  1023.                     ;  with the left mouse button
  1024.                     ;
  1025.                     endif else begin
  1026.                         state.btndown = 1b
  1027.                         state.oWindow->SetProperty, QUALITY=state.dragq
  1028.                         state.oMolecule(state.cur_mol+ $
  1029.                             state.nMolecule)->SetProperty, HIDE=0
  1030.                         state.oMolecule(state.cur_mol)->SetProperty,HIDE=1
  1031.                         WIDGET_CONTROL, state.wDraw, /DRAW_MOTION
  1032.                     endelse
  1033.  
  1034.                 endif   ;  of  sEvent.type EQ 0
  1035.  
  1036.                 ;  Button motion.
  1037.                 ;
  1038.                 if ((sEvent.type eq 2) and  $
  1039.                     (state.btndown eq 1b)) then begin
  1040.  
  1041.                     if (bHaveTransform) then begin
  1042.                         state.oWindow->Draw, state.oView
  1043.                     endif
  1044.                 endif
  1045.  
  1046.                 ;  Button release.
  1047.                 ;
  1048.                 if (sEvent.type eq 1) then begin
  1049.                     state.btndown = 0b
  1050.                     state.oWindow->SetProperty, QUALITY=2
  1051.                     state.oMolecule(state.cur_mol+ $
  1052.                         state.nMolecule)->SetProperty, HIDE=1
  1053.                     state.oMolecule(state.cur_mol)->SetProperty, HIDE=0
  1054.                     state.oWindow->Draw, state.oView
  1055.                     WIDGET_CONTROL, state.wDraw, /DRAW_MOTION
  1056.                 endif
  1057.  
  1058.             endelse
  1059.  
  1060.             WIDGET_CONTROL, sEvent.top, SET_UVALUE=state, /NO_COPY
  1061.  
  1062.         end  ; of DRAW
  1063.  
  1064.         ;  Quit this application.
  1065.         ;
  1066.         'QUIT' : BEGIN
  1067.             WIDGET_CONTROL, sEvent.top, /DESTROY
  1068.         end   ; of QUIT
  1069.  
  1070.         ;  Display the information text file.
  1071.         ;
  1072.         'ABOUT' : BEGIN
  1073.  
  1074.             ; Verify that there is only one instance of Xregistered
  1075.             ;
  1076.             if (Xregistered('XDisplayFile') NE 0) then RETURN
  1077.             XDisplayFile, filepath("object3d.txt", $
  1078.                 SUBDIR=['examples','demo','demotext']), $
  1079.                 DONE_BUTTON='Done', $
  1080.                 TITLE="Objects and molecules", $
  1081.                 GROUP=sEvent.top, WIDTH=55, HEIGHT=14
  1082.         end   ; of ABOUT
  1083.  
  1084.     endcase
  1085.  
  1086. end     ;     of  event handler
  1087.  
  1088. ;-----------------------------------------------------------------
  1089. ;
  1090. ;    PURPOSE : cleanup procedure. restore colortable, destroy objects.
  1091. ;
  1092. pro d_object3d_Cleanup, wBase
  1093.  
  1094.     WIDGET_CONTROL, wBase, GET_UVALUE=state, /NO_COPY
  1095.  
  1096.     ;  Destroy the top objects
  1097.     ;
  1098.     OBJ_DESTROY, state.oView
  1099.     OBJ_DESTROY, state.oContainer
  1100.     OBJ_DESTROY, state.oTrack
  1101.     OBJ_DESTROY, state.oFont
  1102.     OBJ_DESTROY, state.oText
  1103.     OBJ_DESTROY, state.spheres0
  1104.     OBJ_DESTROY, state.spheres1
  1105.     OBJ_DESTROY, state.oSub2MoleModel
  1106.     for i = 0, 2*state.nMolecule-1 do begin
  1107.        OBJ_DESTROY, state.oMolecule(i)
  1108.     endfor
  1109.  
  1110.     ;  Restore the color table.
  1111.     ;
  1112.     TVLCT, state.colorTable
  1113.  
  1114.     if WIDGET_INFO(state.groupBase, /VALID_ID) then $
  1115.         WIDGET_CONTROL, state.groupBase, /MAP
  1116.  
  1117. end   ;  of Texture_Cleanup
  1118.  
  1119. ;----------------------------------------------------------------------------
  1120. ;
  1121. ;   PURPOSE :  display geometric shaped objects ( moleculres, others..)
  1122. ;
  1123. PRO d_object3d, $
  1124.     PATTERN=pattern, $ : IN: (opt) line pattern
  1125.     GROUP=group, $     ; IN: (opt) group identifier
  1126.     APPTLB = appTLB    ; OUT: (opt) TLB of this application
  1127.  
  1128.  
  1129.     ; Check the validity of the group identifier
  1130.     ;
  1131.     ngroup = N_ELEMENTS(group)
  1132.     if (ngroup NE 0) then begin
  1133.         check = WIDGET_INFO(group, /VALID_ID)
  1134.         if (check NE 1) then begin
  1135.             print,'Error, the group identifier is not valid'
  1136.             print, 'Return to the main application'
  1137.             RETURN
  1138.         endif
  1139.         groupBase = group
  1140.     endif else groupBase = 0L
  1141.  
  1142.     ;  Get the screen dimension and define 
  1143.     ;  the dimension of the  drawing area.
  1144.     ;
  1145.     Device, GET_SCREEN_SIZE=screenSize
  1146.     xdim = screenSize(0) * 0.6
  1147.     ydim = xdim * 0.8
  1148.  
  1149.     ;  Get the current color vectors to restore
  1150.     ;  when this application is exited.
  1151.     ;
  1152.     TVLCT, savedR, savedG, savedB, /GET
  1153.  
  1154.     ;  Build color table from color vectors.
  1155.     ;
  1156.     colorTable = [[savedR],[savedG],[savedB]]
  1157.  
  1158.     ;  Get the tips.
  1159.     ;
  1160.     sText = getTips(filepath('object3d.tip', $
  1161.         SUBDIR=['examples','demo', 'demotext']) )
  1162.  
  1163.     ;  Get information on molecules.
  1164.     ;
  1165.     nMolecule = 3      ;  number of molecules
  1166.     files = STRARR(nMolecule)
  1167.  
  1168.     files(0) = 'valium.mol'
  1169.     files(1) = 'aspartam.mol'
  1170.     files(2) = 'caffeine.mol'
  1171.  
  1172.     ; Create widgets.
  1173.     ;
  1174.     if (N_ELEMENTS(group) EQ 0) then begin
  1175.         wBase = WIDGET_BASE(/COLUMN, $
  1176.             XPAD=0, YPAD=0, $
  1177.             /TLB_KILL_REQUEST_EVENTS, $
  1178.             TLB_FRAME_ATTR=1, MBAR=barBase, TITLE="Three Dimensional Geometry")
  1179.     endif else begin
  1180.         wBase = WIDGET_BASE(/COLUMN, $
  1181.             XPAD=0, YPAD=0, $
  1182.             /TLB_KILL_REQUEST_EVENTS, $
  1183.             GROUP_LEADER=group, $
  1184.             TLB_FRAME_ATTR=1, MBAR=barBase, TITLE="Three Dimensional Geometry")
  1185.     endelse
  1186.  
  1187.         ;  Create the menu bar. It contains the file/quit,
  1188.         ;  edit/ shade-style, help/about.
  1189.         ;
  1190.         fileMenu = WIDGET_BUTTON(barBase, VALUE='File', /MENU)
  1191.  
  1192.             wQuitButton = WIDGET_BUTTON(fileMenu, VALUE='Quit', UVALUE='QUIT')
  1193.  
  1194.  
  1195.         ;  Create the menu bar item Edit
  1196.         ;  that has the shade and style options
  1197.         ;
  1198.         wEditButton = WIDGET_BUTTON(barBase, VALUE='Options', /MENU)
  1199.  
  1200.             wShadingButton = WIDGET_BUTTON( wEditButton, $
  1201.                 VALUE='Shading', UVALUE='SHADING', MENU=1)
  1202.  
  1203.                 wFlatButton = WIDGET_BUTTON(wShadingButton, $
  1204.                     VALUE='Flat', UVALUE='FLAT')
  1205.  
  1206.                 wGouraudButton = WIDGET_BUTTON(wShadingButton, $
  1207.                     VALUE='Gouraud', UVALUE='GOURAUD')
  1208.  
  1209.             wStyleButton = WIDGET_BUTTON(wEditButton, $
  1210.                 VALUE='Style', UVALUE='STYLE', /MENU)
  1211.  
  1212.                 wPointsButton = WIDGET_BUTTON(wStyleButton, $
  1213.                     VALUE='Points', UVALUE='POINTS')
  1214.  
  1215.                 wWireButton = WIDGET_BUTTON(wStyleButton, $
  1216.                     VALUE='Wire', UVALUE='WIRE')
  1217.  
  1218.                 wSolidButton = WIDGET_BUTTON(wStyleButton, $
  1219.                     VALUE='Solid', UVALUE='SOLID')
  1220.  
  1221.                 wPointhButton = WIDGET_BUTTON(wStyleButton, $
  1222.                     VALUE='Hidden Points', UVALUE='POINTSH')
  1223.  
  1224.                 wWirehButton = WIDGET_BUTTON(wStyleButton, $
  1225.                     VALUE='Hidden Wire', UVALUE='WIREH')
  1226.  
  1227.             tBack = WIDGET_BUTTON(wEditButton, $
  1228.                 VALUE="Backface Culling (off)", UVALUE='BACKF')
  1229.  
  1230.             tVc = Widget_Button(wEditButton, $
  1231.                 VALUE="Vertex Coloring (on )", UVALUE='VERTC')
  1232.  
  1233.             tEdging = WIDGET_BUTTON(wEditButton, $
  1234.                 VALUE="Edging (off)", UVALUE='EDGING')
  1235.  
  1236.             wBottomButton = WIDGET_BUTTON(wEditButton, $
  1237.                 VALUE="Bottom Color (on )", UVALUE='BOTTOM')
  1238.  
  1239.             wThickButton = WIDGET_BUTTON(wEditButton, $
  1240.                 MENU=2, VALUE="Line Thickness")
  1241.  
  1242.                 wThk1 = WIDGET_BUTTON(wThickButton, $
  1243.                     VALUE='1', UVALUE='THCK1')
  1244.  
  1245.                 wThk3 = WIDGET_BUTTON(wThickButton, $
  1246.                     VALUE='3', UVALUE='THCK3')
  1247.  
  1248.                 wThk5 = WIDGET_BUTTON(wThickButton, $
  1249.                     VALUE='5', UVALUE='THCK5')
  1250.  
  1251.                 wThk7 = WIDGET_BUTTON(wThickButton, $
  1252.                     VALUE='7', UVALUE='THCK7')
  1253.  
  1254.  
  1255.         ;  Create the drag buttons
  1256.         ;
  1257.         wOptionButton = WIDGET_BUTTON(barBase, VALUE='Drag', /MENU)
  1258.  
  1259.             tDrag = WIDGET_BUTTON(wOptionButton, $
  1260.                 VALUE="Drag Quality", UVALUE='DRAGQ', /MENU)
  1261.  
  1262.                 wLowButton = WIDGET_BUTTON(tdrag, $
  1263.                     VALUE='Low', UVALUE='LOW')
  1264.  
  1265.                 wMediumButton = WIDGET_BUTTON(tdrag, $
  1266.                     VALUE='Medium', UVALUE='MEDIUM')
  1267.  
  1268.                 wHighButton = WIDGET_BUTTON(tdrag, $
  1269.                     VALUE='High', UVALUE='HIGH')
  1270.  
  1271.         ;  Create the help|About button.
  1272.         ;
  1273.         helpMenu = WIDGET_BUTTON(barBase, VALUE='About', /HELP, /MENU)
  1274.  
  1275.             wAboutButton = WIDGET_BUTTON(helpMenu, $
  1276.                 VALUE='About 3-D Geometry', UVALUE='ABOUT')
  1277.  
  1278.         ; Create a sub base of the top base (wBase)
  1279.         ;
  1280.         subBase = WIDGET_BASE(wBase, COLUMN=2)
  1281.  
  1282.  
  1283.             ;  Create the left Base that contains the functionality buttons
  1284.             ;  Notably the object list and the option list
  1285.             ;
  1286.             wLeftbase = WIDGET_BASE(subBase, $
  1287.                 /BASE_ALIGN_CENTER, /COLUMN)
  1288.  
  1289.                 wObjectBase = WIDGET_BASE(wLeftBase, /COLUMN, $
  1290.                     /BASE_ALIGN_CENTER)
  1291.  
  1292.                     wObjectLabel = WIDGET_LABEL(wObjectBase, $
  1293.                         VALUE='Objects' )
  1294.  
  1295.                     wObjectBgroup = cw_bgroup(wObjectBase, $
  1296.                         [ 'Seashell','Knot','Teapot', $
  1297.                           'Valium Molecule', 'Aspartame Molecule', $
  1298.                           'Caffeine Molecule'], $
  1299.                         /COLUMN, $
  1300.                         /EXCLUSIVE, $
  1301.                         /NO_RELEASE, $
  1302.                         /RETURN_INDEX, $
  1303.                         SET_VALUE=0, $
  1304.                         UVALUE='OBJ')
  1305.  
  1306.                 wScalingBase = WIDGET_BASE(wLeftBase, $
  1307.                     /COLUMN, YPAD=5)
  1308.                  
  1309.                     percent = 100
  1310.                     scalingString = 'Scaling : ' + STRING(percent, $
  1311.                         FORMAT='(f5.1)') + ' %'
  1312.                     wScalingLabel = WIDGET_LABEL(wScalingBase, $
  1313.                         VALUE=scalingString)
  1314.  
  1315.                     wScalingSlider = WIDGET_SLIDER(wScalingBase, $
  1316.                         MINIMUM=0, $
  1317.                         MAXIMUM=50, VALUE=25, $
  1318.                         /SUPPRESS_VALUE, $
  1319.                         UVALUE='SCALING')
  1320.  
  1321.                 wResetBase = WIDGET_BASE(wLeftBase, /COLUMN, YPAD=5)
  1322.  
  1323.                     wResetLabel = WIDGET_LABEL(wResetBase, $
  1324.                         VALUE='Reset Orientation')
  1325.  
  1326.                     wResetButton = WIDGET_BUTTON(wResetBase, $
  1327.                         VALUE="Reset", UVALUE='RESETTRANSFORM')
  1328.  
  1329.             ; Create the right Base that has the drawing area
  1330.             ;
  1331.             wRightbase = WIDGET_BASE(subBase, /COLUMN)
  1332.  
  1333.                 wDraw = widget_draw(wRightBase, $
  1334.                     GRAPHICS_LEVEL=2, $  
  1335.                     XSIZE=xdim, YSIZE=ydim, /BUTTON_EVENTS, $
  1336.                     UVALUE='DRAW', $
  1337.                     RETAIN=0, /EXPOSE_EVENTS)
  1338.  
  1339.         ;  Create tips texts.
  1340.         ;
  1341.         wStatusBase = WIDGET_BASE(wBase, MAP=0, /ROW)
  1342.  
  1343.             nWidgets = 2
  1344.             wText = LONARR(nWidgets)
  1345.             widTips, wStatusBase, sText.text, XSIZE=36, $
  1346.                 YSIZE=3, NWIDGETS=nWidgets, wText
  1347.  
  1348.     ;  Realize the base widget.
  1349.     ;
  1350.     WIDGET_CONTROL, wBase, /REALIZE
  1351.  
  1352.     WIDGET_CONTROL, /HOURGLASS
  1353.  
  1354.     ;  Returns the top level base in the appTLB keyword.
  1355.     ;
  1356.     appTLB = wBase
  1357.  
  1358.     ;  Size the tips widgets.
  1359.     ;
  1360.     sizeTips, wBase, wText, wStatusBase
  1361.  
  1362.     WIDGET_CONTROL, wBase, SENSITIVE=0
  1363.  
  1364.     ; Grab the window id of the drawable.
  1365.     ;
  1366.     WIDGET_CONTROL, wDraw, GET_VALUE=oWindow
  1367.  
  1368.     ; Compute viewplane rect based on aspect ratio.
  1369.     ;
  1370.     aspect = float(xdim)/float(ydim)
  1371.     myview = [-0.5,-0.5,1,1]
  1372.     if (aspect > 1) then begin
  1373.         myview(0) = myview(0) - ((aspect-1.0)*myview(2))/2.0
  1374.         myview(2) = myview(2) * aspect
  1375.     endif else begin
  1376.         myview(1) = myview(1) - (((1.0/aspect)-1.0)*myview(3))/2.0
  1377.         myview(3) = myview(3) * aspect
  1378.     endelse
  1379.  
  1380.     ; Create view.
  1381.     ;
  1382.     oView = OBJ_NEW('idlgrview', PROJECTION=2, EYE=3, ZCLIP=[1.5,-1.5],$
  1383.         VIEWPLANE_RECT=myview, COLOR=[0,0,0])
  1384.  
  1385.     ;  Create a centered starting up text.
  1386.     ;
  1387.     textLocation = [myview[0]+0.5*myview[2], myview[1]+0.5*myview[3]]
  1388.  
  1389.     ;  Create and display the PLEASE WAIT text.
  1390.     ;
  1391.     oFont = OBJ_NEW('IDLgrFont', 'Helvetica', SIZE=18)
  1392.     oText = OBJ_NEW('IDLgrText', $
  1393.         'Starting up  Please wait...', $
  1394.         ALIGN=0.5, $
  1395.         LOCATION=textLocation, $
  1396.         COLOR=[255,255,0], FONT=oFont)
  1397.  
  1398.     ; Create models and objects for the modlecules .
  1399.     ;
  1400.     nMolecule = 3      ;  number of molecules
  1401.     oMoleModel = OBJ_NEW('idlgrModel')
  1402.     oSub1MoleModel = OBJ_NEW('idlgrModel')
  1403.     oSub2MoleModel = OBJ_NEW('idlgrModel')
  1404.     oView->Add, oMoleModel
  1405.     oMoleModel->Add, oSub1MoleModel
  1406.     oMoleModel->Add, oText
  1407.     oWindow->Draw, oView
  1408.  
  1409.     scm = 0.3
  1410.     oMoleModel->Scale, scm, scm, scm
  1411.     oMolecule = OBJARR(nMolecule*2)
  1412.     spheres0 = makeSpheres()
  1413.     spheres1 = makeSpheres()
  1414.  
  1415.     for i = 0, N_ELEMENTS(spheres1)-1 do begin
  1416.         spheres1(i)->SetProperty, DENSITY=0.3
  1417.     endfor
  1418.  
  1419.     for i = 0, N_ELEMENTS(spheres0)-1 do begin
  1420.         spheres0(i)->SetProperty, DENSITY=0.9
  1421.     endfor
  1422.  
  1423.     high = FLTARR(3)
  1424.     low = FLTARR(3)
  1425.  
  1426.     for i=0,nMolecule-1  do begin
  1427.         n = molread(files(i), xyz, type)
  1428.  
  1429.         for j=0,2  do begin
  1430.             high(j) = max(xyz(j,*))
  1431.             low(j) = min(xyz(j,*))
  1432.         endfor
  1433.  
  1434.         sc = 2.0/float(high(0)-low(0))
  1435.         oMolecule(i) = makemolecule(n, xyz, type, spheres0)
  1436.         oMolecule(i)->Scale, sc, sc, sc
  1437.         oSub1MoleModel->Add, oMolecule(i)
  1438.  
  1439.         oMolecule(i)->SetProperty, HIDE=1
  1440.  
  1441.         oMolecule(i+nMolecule) = makemolecule(n,xyz,type,spheres1)
  1442.         oMolecule(i+nMolecule)->Scale, sc, sc, sc
  1443.         oMolecule(i+nMolecule)->SetProperty, HIDE=1
  1444.         oSub1MoleModel->add,oMolecule(i+nMolecule)
  1445.     endfor
  1446.  
  1447.     ;  Create some lights.
  1448.     ;
  1449.     oLight1 = OBJ_NEW('IDLgrLight', $
  1450.         LOCATION=[2,2,5], TYPE=2, COLOR=[255,255,255], $
  1451.         INTENSITY=0.25 )
  1452.  
  1453.     oMoleModel->Add, oLight1
  1454.  
  1455.     oLight2 = OBJ_NEW('IDLgrLight', TYPE=0, $
  1456.         INTENSITY=0.5, COLOR=[255,255,255])
  1457.  
  1458.     oMoleModel->add,oLight2
  1459.  
  1460.     ;  Hide the molecule model.
  1461.     ;
  1462.     oMoleModel->SetProperty, HIDE=1
  1463.  
  1464.     ;  Create model for the geometric objects.
  1465.     ;
  1466.     oShapeModel = OBJ_NEW('IDLgrModel')
  1467.     oShape0Model = OBJ_NEW('IDLgrModel') 
  1468.     oShapeModel->Add, oShape0Model
  1469.     goff = OBJ_NEW('IDLgrModel')
  1470.     oShapeModel->Add, goff
  1471.     goff->translate, 0, 0, 0.005
  1472.     oShape1Model = OBJ_NEW('IDLgrModel')
  1473.     goff->Add, oShape1Model 
  1474.  
  1475.     max_obj = 3   ;  number of objects
  1476.     oSurface = OBJARR(max_obj)
  1477.  
  1478.     scs = 0.7
  1479.     oShapeModel->Scale, scs, scs, scs
  1480.  
  1481.     ;  Read_noff can be used to read modified .noff format files
  1482.     ;  which are ascii data files containing a mesh description
  1483.     ;  The d_object3d demo uses object3d_read_data to read binary
  1484.     ;  files which contain the meshes which were originally in ascii files.
  1485.     ;oSurface(0) = read_noff('seashell.nof', oShape0Model, xr, yr, zr)
  1486.     ;oSurface(1) = read_noff('knot.nof', oShape0Model, xr, yr, zr)
  1487.     ;oSurface(2) = read_noff('teapot.nof', oShape0Model, xr, yr, zr)
  1488.     oSurface(0) = object3d_read_data('seashell.dat', oShape0Model, xr, yr, zr)
  1489.     oSurface(1) = object3d_read_data('knot.dat', oShape0Model, xr, yr, zr)
  1490.     oSurface(2) = object3d_read_data('teapot.dat', oShape0Model, xr, yr, zr)
  1491.  
  1492.     ;  Create the vertex colors and make the 3-D objects
  1493.     ; to hqve these color.
  1494.     ;
  1495.     vc = BYTARR(3, 360, /NOZERO)
  1496.     sat = 1.0
  1497.     val = 1.0
  1498.     for i = 0, 359 do begin
  1499.         angle = i
  1500.         Color_convert, angle, sat, val, red, green, blue, /HSV_RGB
  1501.         vc(0, i) = red
  1502.         vc(1, i) = green
  1503.         vc(2, i) = blue
  1504.     endfor
  1505.  
  1506.     for i = 0, 2 do begin
  1507.         oSurface(i)->SetProperty, VERT_COLORS=vc
  1508.     endfor
  1509.  
  1510.     for i = 1, max_obj-1 do begin 
  1511.         oSurface(i)->SetProperty, HIDE=1 
  1512.     endfor
  1513.  
  1514.     for i=0,max_obj-1 do begin
  1515.      oSurface(i)->GetProperty, XRANGE=xr, YRANGE=yr, ZRANGE=zr
  1516.     endfor
  1517.  
  1518.     ;  Cook up polyline objects using share_data.
  1519.     ;
  1520.     sh = OBJARR(max_obj)
  1521.     for i=0,max_obj-1  do begin
  1522.         oSurface(i)->GetProperty, POLY=pmesh 
  1523.         sh(i) = OBJ_NEW('IDLgrPolyline', COLOR=[0,0,0], $
  1524.         SHARE_DATA=oSurface(i), POLYLINE=pmesh, HIDE=1)
  1525.         oShape1Model->Add, sh(i)
  1526.     endfor
  1527.  
  1528.     ; Create some lights.
  1529.     ;
  1530.     oLight3 = OBJ_NEW('IDLgrLight', LOCATION=[2,2,5], TYPE=1, $ 
  1531.         COLOR=[200,0,0])
  1532.     oShapeModel->Add, oLight3
  1533.  
  1534.     oLight4 = OBJ_NEW('IDLgrLight', LOCATION=[0,0,5], TYPE=1, $
  1535.         COLOR=[180,180,180], INTENSITY=0.5)
  1536.     oShapeModel->Add, oLight4
  1537.  
  1538.     oLight5 = OBJ_NEW('IDLgrLight', TYPE=0, INTENSITY=0.3, $
  1539.         COLOR=[100,100,255])
  1540.     oShapeModel->Add, oLight5
  1541.  
  1542.     ;  Set the line pattern.
  1543.     ;
  1544.     if (N_Elements(Pattern) NE 0) then begin
  1545.         pat = BYTARR(4,2,16)
  1546.         pat(*,0,*) = 'AA'X
  1547.         pat(*,1,*) = '55'X
  1548.  
  1549.         if (Pattern NE 1) then begin
  1550.             pobj= OBJ_NEW('IDLgrPattern','PATTERN',pattern=pat)
  1551.         endif else begin
  1552.             pobj= OBJ_NEW('IDLgrPattern','LINEFILL',$
  1553.         spacing=10,orientation=30,thick=4)
  1554.         endelse
  1555.  
  1556.         for i=0, max_obj do begin
  1557.             oSurface(i)->SetProperty,fill_pattern=pobj
  1558.         endfor
  1559.  
  1560.         tPAnim = WIDGET_BUTTON(wOptions, $
  1561.             VALUE="Pat Animate", UVALUE='PANIMATE')
  1562.     endif
  1563.  
  1564.     ; Place the model in the view.
  1565.     ;
  1566.     oView->Add, oShapeModel
  1567.  
  1568.     ;  Desensitize the appropriate buttons.
  1569.     ;
  1570.     WIDGET_CONTROL, wGouraudButton, SENSITIVE=0
  1571.     WIDGET_CONTROL, wSolidButton, SENSITIVE=0
  1572.     WIDGET_CONTROL, wMediumButton, SENSITIVE=0
  1573.     WIDGET_CONTROL, wThk1, SENSITIVE=0
  1574.     WIDGET_CONTROL, wThickButton, SENSITIVE=0
  1575.  
  1576.     oShape0Model->GetProperty, TRANSFORM=tmg0
  1577.     oShape1Model->GetProperty, TRANSFORM=tmg1
  1578.     oSub1MoleModel->GetProperty, TRANSFORM=tmMolecule
  1579.  
  1580.     ; Create a structure that has the widget ID
  1581.     ;
  1582.     widgetIDStr = { $
  1583.         WBase : wBase, $                    ; Top level base
  1584.         WEditButton : wEditButton, $
  1585.         WQuitButton : wQuitButton, $
  1586.         WAboutButton : wAboutButton, $
  1587.         WFlatButton : wFlatButton, $
  1588.         WGouraudButton : wGouraudButton, $
  1589.         WPointsButton : wPointsButton, $
  1590.         WWireButton : wWireButton, $
  1591.         WSolidButton : wSolidButton, $
  1592.         WPointhButton : wPointhButton, $
  1593.         WWirehButton : wWirehButton, $
  1594.         WLowButton : wLowButton, $
  1595.         WMediumButton : wMediumButton, $
  1596.         WHighButton : wHighButton, $
  1597.         WBottomButton : wBottomButton, $
  1598.         WThickButton : wThickButton, $
  1599.         wObjectBgroup : wObjectBgroup, $
  1600.         WScalingSlider : wScalingSlider, $
  1601.         WScalingLabel : wScalingLabel, $
  1602.         WThk1 : wThk1, $                   ; Line thickness buttons
  1603.         WThk3 : wThk3, $
  1604.         WThk5 : wThk5, $
  1605.         WThk7 : wThk7 $
  1606.     }
  1607.  
  1608.     ;  Add the trackball object for interactive change
  1609.     ;  of the scene orientation.
  1610.     ;
  1611.     oTrack = OBJ_NEW('Trackball', [xdim/2.0, ydim/2.0], xdim/2.0)
  1612.  
  1613.     oContainer = OBJ_NEW('IDLgrContainer')
  1614.     oContainer->Add, oView
  1615.     oContainer->Add, oTrack
  1616.  
  1617.  
  1618.     ; Save state.
  1619.     ;
  1620.     state = { $
  1621.         tmg0: tmg0, $                     ; Transformation matrix for model g0
  1622.         tmg1: tmg1, $                     ; Transformation matrix for model g1
  1623.         tmmolecule: tmmolecule, $         ; Transformation matrix for molecule
  1624.         ModelFlag:1, $                    ; 0 = molecule , 1 = object
  1625.         btndown: 0b, $                    ; 0 = bottom not pressed, pressed otherwise
  1626.         wDraw: wDraw, $                   ; Widget draw ID
  1627.         OShapeModel: oShapeModel, $       ; 3-D objects model
  1628.         OMoleModel: oMoleModel, $         ; Molecule model
  1629.         Spheres0: spheres0, $             ; Spheres objects for molecules
  1630.         Spheres1: spheres1, $   
  1631.         OShape0Model: oShape0Model, $     ; Models for 3-D objects
  1632.         OShape1Model: oShape1Model, $
  1633.         OSurface: oSurface, $             ; Surface object
  1634.         OMolecule: oMolecule, $           ; Molecule object
  1635.         sh : sh, $                        ; Share data (3-D objects)
  1636.         OView: oView, $                   ; View object
  1637.         OWindow: oWindow, $               ; Window object
  1638.         max_obj: max_obj, $               ; Number of 3-D objects
  1639.         NMolecule: nMolecule, $           ; Number of molecule
  1640.         cur_obj: 0, $                     ; Current 3-D object
  1641.         cur_mol: 0, $                     ; Current molecule
  1642.         cur_sel: oSub2MoleModel, $        ; Molecule models
  1643.         OSub1MoleModel: oSub1MoleModel, $
  1644.         OSub2MoleModel: oSub2MoleModel, $
  1645.         OContainer: oContainer, $         ; Container object
  1646.         OTrack: oTrack, $                 ; Trackball object
  1647.         is_sel: 0, $                      ; Is selected flag (for picking molecule)
  1648.         edging: 0, $                      ; Edges flag (0=not showing, 1=showing)
  1649.         WidgetIDStr : widgetIDStr, $      ; Structure of all the widget IDS
  1650.         Initial:0, $                      ; Indicates if initial draw
  1651.         ColorTable: colorTable, $         ; Color table to restore
  1652.         SText: sText, $                   ; Text structure for tips
  1653.         OText: oText, $                   ; Text object
  1654.         OFont: oFont, $                   ; Font object
  1655.         WText: wText, $                   ; Widget text IDs for tips
  1656.         Vc: vc, $                         ; Vertex colors array
  1657.         dragq: 1, $                       ; Drag quality (0=low, 1=med., 2=high)
  1658.         groupBase: groupBase $            ; Base of Group Leader
  1659.     }
  1660.    
  1661.     WIDGET_CONTROL, wBase, SET_UVALUE=state, /NO_COPY
  1662.  
  1663.  
  1664.     WIDGET_CONTROL, wBase, SENSITIVE=1
  1665.  
  1666.     oMoleModel->Remove, oText
  1667.  
  1668.     oWindow->Draw, oView
  1669.  
  1670.     XMANAGER, 'd_object3d', wBase, Event_Handler='d_object3d_Event', $
  1671.         /NO_BLOCK, $
  1672.         CLEANUP='d_object3d_cleanup'
  1673.  
  1674. end   ;   of   d_object3d
  1675.